<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>immutableInsert</title>
</head>

<body>
    <div>打开浏览器控制台查看结果</div>
    <script>
        const immutableInsert = (data, keyPath, insertVal) => {
            const deepClone = obj => {
                if (obj === null) {
                    return null;
                }
                let clone = Object.assign({}, obj);
                Object.keys(clone).forEach(
                    key =>
                    (clone[key] =
                        typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
                );
                if (Array.isArray(obj)) {
                    clone.length = obj.length;
                    return Array.from(clone);
                }
                return clone;
            };
            const insert = (newData, newKeyPath) => {
                const key = newKeyPath.shift(),
                    index = newKeyPath.shift(),
                    len = newKeyPath.length;
                if (len > 0) {
                    insert(newData[key][index], newKeyPath);
                } else {
                    newData[key].splice(index, 0, insertVal);
                }
            };
            return insert(deepClone(data), keyPath);
        };
        const data = {
            id: 'id0',
            name: 'root',
            fields: [
                {
                    id: 'id1',
                    name: 'name 1-1',
                    fields: [
                        {
                            id: 'id1-1',
                            name: 'name 1-1'
                        },
                        {
                            id: 'id1-2',
                            name: 'name 1-2',
                            fields: [
                                {
                                    id: 'targetId'
                                }
                            ]
                        }
                    ]
                },
                {
                    id: 'id2',
                    name: 'name 2-1',
                    fields: [
                        {
                            id: 'id2-1',
                            name: 'name 2-1'
                        }
                    ]
                }
            ]
        };
        console.log(
            immutableInsert(data, ['fields', 0, 'fields', 1, 'fields', 0], {
                id: 'newId'
            })
        );
    </script>
</body>

</html>